package com.train.mgr.config.thread;

import cn.hutool.core.exceptions.UtilException;
import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * 统计使用的线程池
 */
@Slf4j
public class ThreadPool {

    private static ExecutorService executor;

    public static ThreadPool threadPool;
    //线程池的基本大小
    private static final int corePoolSize = 30;
    //线程池中允许的最大线程数
    private static final int maximumPoolSize = 100;
    //线程池中空闲线程等待工作的超时时间(秒)
    private static final long keepAliveTime =60;

    private ThreadPool() {
        init();
    }

    /**
     * 获取单一实例
     *
     * @return
     */
    public static ThreadPool getInstance() {
        if (threadPool == null) {
            threadPool = new ThreadPool();
        }
        return threadPool;
    }

    /**
     * 初始化线程池
     */
    private void init() {
        if (null != executor) {
            executor.shutdownNow();
        }
        executor = SpringUtil.getBean(ThreadPoolTaskExecutor.class).getThreadPoolExecutor();
    }

    /**
     * 关闭线程池
     *
     * @param isNow 是否立即关闭而不等待正在执行的线程
     */
    synchronized public void shutdown(boolean isNow) {
        if (null != executor) {
            if (isNow) {
                executor.shutdownNow();
            } else {
                executor.shutdown();
            }
        }
    }

    /**
     * 获得  ExecutorService
     */
    public ExecutorService getExecutor() {
        return executor;
    }

    /**
     * 线程池中执行线程
     *
     * @param runnable 可运行对象
     */
    public void execute(Runnable runnable) {
        try {
            executor.execute(runnable);
        } catch (Exception e) {
            throw new UtilException(e, "Exception when running task!");
        }
    }

    /**
     * 执行有返回值的异步方法<br>
     * Future代表一个异步执行的操作，通过get()方法可以获得操作的结果，如果异步操作还没有完成，则，get()会使当前线程阻塞
     *
     * @param <T>  执行的Task
     * @param task
     * @return Future
     */
    public <T> Future<T> submit(Callable<T> task) {
        return executor.submit(task);
    }

    /**
     * 执行有返回值的异步方法<br>
     * Future代表一个异步执行的操作，通过get()方法可以获得操作的结果，如果异步操作还没有完成，则，get()会使当前线程阻塞
     *
     * @param runnable 可运行对象
     * @return
     */
    public Future<?> submit(Runnable runnable) {
        return executor.submit(runnable);
    }

    /**
     * 投递任务至线程池
     *
     * @param runnable
     */
    public static void submit2Pool(Runnable runnable) {
        ThreadPool.getInstance().submit(runnable);
    }

}
